# -*- coding:utf-8 -*-
# vim: set et sw=4 ts=4 sts=4 ff=unix fenc=utf8:

from .. import errors


def create_vm_instance(client, name, l3_network_uuids, image_uuid,
                       instance_offering_uuid, default_network_uuid=None,
                       async=False, period=1):
    if isinstance(l3_network_uuids, type(u'')):
        l3_network_uuids = [l3_network_uuids]
    default_network_uuid = l3_network_uuids[0] if default_network_uuid is None else default_network_uuid
    rsp = client.create_vm_instance({
        'dataDiskOfferingUuids': [],
        'defaultL3NetworkUuid': default_network_uuid,
        'description': '',
        'imageUuid': image_uuid,
        'instanceOfferingUuid': instance_offering_uuid,
        'l3NetworkUuids': l3_network_uuids,
        'name': name,
        'strategy': 'InstantStart',
        # 'systemTags': []}, async=False))
        'systemTags': []
    }, async=async, period=period)
    client.log.info('[ZStack for OSYL] CreateVmInstance API succeed [%s]' % client.username)
    return rsp


def destroy_vm_instance(client, uuid, async=False):
    data = {'uuid': uuid}
    rsp = client.destroy_vm_instance(data, async=False)
    client.log.info('[ZStack for OSYL] DestroyVmInstance API succeed [%s]' % client.username)
    try:
        rsp = client.expunge_vm_instance(data, async=async)
        client.log.info('[ZStack for OSYL] ExpungeVmInstance API succeed [%s]' % client.username)
    except errors.ZStackException:
        pass
    return rsp


def query_instance_offering(client):
    return client.query_instance_offering()


def query_instance_offering_by_uuid(client, uuid):
    data = {'conditions': [{'name': 'uuid',
                            'op': '=',
                            'value': uuid}]}
    return client.query_instance_offering(data)


def query_instance_offering_by_type_is_vm(client):
    data = {'conditions': [{'name': 'type',
                            'op': '=',
                            'value': 'UserVm'}]}
    return client.query_instance_offering(data)


def create_instance_offering(client, name, cpu_num, memory_size, cpu_speed=1):
    data = {'name': name,
            'cpuNum': cpu_num,
            'cpuSpeed': cpu_speed,
            'memorySize': int(memory_size) * 1024 * 1024}
    return client.create_instance_offering(data)


def delete_instance_offering(client, uuid):
    data = {'uuid': uuid}
    return client.delete_instance_offering(data)


def enable_instance_offering_state(client, uuid):
    data = {'stateEvent': 'enable',
            'uuid': uuid}
    return client.enable_instance_offering_state(data)


def disable_instance_offering_state(client, uuid):
    data = {'stateEvent': 'disable',
            'uuid': uuid}
    return client.disable_instance_offering_state(data)


def do_action_vm(client, uuid, action=''):
    callbacks = {
        'start': client.start_vm_instance(data={'uuid': uuid}),
        'pause': client.pause_vm_instance(data={'uuid': uuid}),
        'unpause': client.resume_vm_instance(data={'uuid': uuid}),  # TODO
        'stop': client.stop_vm_instance(data={'uuid': uuid}),
        'reboot': client.reboot_vm_instance(data={'uuid': uuid}),
        'suspend': client.pause_vm_instance(data={'uuid': uuid}),  # TODO
        'resume': client.resume_vm_instance(data={'uuid': uuid}),
        'delete': client.destroy_vm_instance(data={'uuid': uuid}),
        'vnc-console': client.request_console_access(data={'vmInstanceUuid': uuid}),
        'console-log': None  # TODO
    }
    return callbacks.get(action)


def query_vm_instance(client):
    return client.query_vm_instance()


def query_vm_instance_by_username(client, username, details=True):
    users = client.query_account(data={
        'conditions': [{"name": "name", "value": username, "op": "="}], 'fields': ['uuid']})
    if len(users) != 1:
        raise errors.ZStackException('Query vm instance by username [%s] error, [%s]' % (username, str(users)))
    else:
        user_uuid = users[0].get('uuid')
        print(user_uuid)

    vms_uuid = [vm.get('resourceUuid') for vm in client.query_account_resource_ref(data={
        'conditions': [{'name': 'accountUuid', 'op': '=', 'value': user_uuid},
                       {'name': 'resourceType', 'op': '=', 'value': 'VmInstanceVO'}],
        'fields': ['resourceUuid']})]

    data = {'conditions': [{'name': 'uuid', 'op': 'in', 'value': ','.join(vms_uuid)}]}
    if not details:
        data['fields'] = ['name', 'uuid', 'vmNics', 'imageUuid', 'instanceOfferingUuid']

    return client.query_vm_instance(data=data)


def query_vm_instance_by_hosts_name(client, hosts_name, details=True):
    if isinstance(hosts_name, type(u'')):
        hosts_name = [hosts_name]
    hosts_uuid = [host.get('uuid') for host in client.query_host(data={
        'conditions': [{'name': 'name', 'op': 'in', 'value': ','.join(hosts_name)}],
        'fields': ['name', 'uuid']
    })]

    data = {'conditions': [{'name': 'hostUuid', 'op': 'in', 'value': ','.join(hosts_uuid)}]}
    if not details:
        data['fields'] = ['name', 'uuid', 'vmNics', 'imageUuid', 'instanceOfferingUuid']
    return client.query_vm_instance(data=data)


def query_vm_nic_by_vm_instance_uuid(client, uuid):
    data = {'conditions': [{'name': 'vmInstanceUuid',
                            'op': '=',
                            'value': uuid}]}
    return client.query_vm_nic(data=data)


def query_eip_by_vm_instance_uuid(client, uuid):
    """
    根据虚拟机uuid查询EIP

    :param client:
    :param uuid:
    :return: {'ips': [ips], nic_uuid: [eips_info]}
    """
    nics = client.query_vm_nic(data={'conditions': [{'name': 'vmInstanceUuid', 'op': '=', 'value': uuid}],
                                     'fields': ['uuid']})
    nics_eips = {'ips': []}
    for nic in nics:
        nic_eips = client.query_eip(data={
            'conditions': [{'name': 'vmNicUuid', 'op': '=', 'value': nic.get('uuid')}]})
        nics_eips[nic.get('uuid')] = nic_eips
        nics_eips['ips'].extend([_.get('vipIp') for _ in nic_eips])
    return nics_eips
